/*
 * Copyright (c) www.bugull.com
 */

package com.bugull.farm.core.codec;

import com.bugull.farm.core.cache.PropertiesCache;
import com.bugull.farm.core.crypto.Crypto;
import com.bugull.farm.core.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 *
 * @author Frank Wen(xbwen@hotmail.com)
 */
public class DefaultCryptoEncoder extends MessageToByteEncoder<ByteBuf> {

    @Override
    protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
        if(msg.readableBytes() < PropertiesCache.getInstance().getInt("frame.min.size")){
            return;
        }
        byte flag = msg.getByte(1);
        boolean encrypted = ByteUtil.getBit(flag, 6);
        if(!encrypted){
            out.writeBytes(msg);
        }
        else{
            out.writeByte(msg.readByte());  //PV
            out.writeByte(msg.readByte());  //Flag
            msg.readBytes(out, 6);  //Mac

            int len = msg.readUnsignedByte();  //Len
            byte[] srcBytes = new byte[len];
            msg.readBytes(srcBytes);
            Crypto crypto = new Crypto("AES","CBC/PKCS5Padding");
            crypto.setIV(PropertiesCache.getInstance().get("default.aes.key").getBytes(PropertiesCache.getInstance().get("charset.utf8")));
            byte[] encryBytes = crypto.encrypt(srcBytes, PropertiesCache.getInstance().get("default.aes.key").getBytes(PropertiesCache.getInstance().get("charset.utf8")));
            out.writeByte(encryBytes.length);
            out.writeBytes(encryBytes);
        }
    }

}
